#ifndef __WD_FUNC_H
#define __WD_FUNC_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <error.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/epoll.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <sys/uio.h>

#define SIZE(a) (sizeof(a)/sizeof(a[0]))

typedef void (*sighandler_t)(int);

#define ARGS_CHECK(argc, num)   {\
    if(argc != num){\
        fprintf(stderr, "ARGS ERROR!\n");\
        return -1;\
    }}

#define ERROR_CHECK(ret, num, msg) {\
    if(ret == num) {\
        perror(msg);\
        return -1;\
    }}

#define THREAD_ERROR_CHECK(ret, func) {\
    if(ret != 0) {\
        fprintf(stderr, "%s:%s\n", func, strerror(ret));\
    }}

#define LOG_INFO(type, content) {\
    log_info(type, content, __FILE__, __LINE__, __FUNCTION__);\
}

#define EVENT_ARR_SIZE 100

// 传输的数据类型
typedef enum {
    CMD_TYPE_PWD=1,
    CMD_TYPE_LS,
    CMD_TYPE_CD,
    CMD_TYPE_MKDIR,
    CMD_TYPE_RMDIR,
    CMD_TYPE_PUTS,
    CMD_TYPE_GETS,
    CMD_TYPE_NOTCMD  //不是命令
}CmdType;

// 传输的SLV协议封装
typedef struct 
{
    int len;//记录内容长度
    CmdType type;
    char buff[1000];//记录内容本身
}train_t;

//任务节点
typedef struct task_s {
    int peerfd;
    struct task_s * pNext;
    char data[1000];
    CmdType type;
    int is_logged;
    char current_dir[1024];
}task_t;


typedef struct taskqueue_s{
    task_t * pFront;
    task_t * pRear;
    int queueSize;//记录当前任务数量
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    int exitFlag;
}task_queue_t;

typedef struct threadpool_s {
    pthread_t * pthreads;
    int threadNum;
    task_queue_t queue;
}threadpool_t;

void queueInit(task_queue_t * que);
void queueDestroy(task_queue_t * que);
int taskSize(task_queue_t * que);
int queueIsEmpty(task_queue_t * que);
void taskEnqueue(task_queue_t * que, int peerfd);
task_t* taskDequeue(task_queue_t * que);
void broadcastAll(task_queue_t * que);

void * threadFunc(void * arg);
void threadpoolInit(threadpool_t *, int num);
void threadpoolDestroy(threadpool_t *);
void threadpoolStart(threadpool_t *);
void threadpoolStop(threadpool_t *);

int sendn(int sockfd, const void * buff, int len);
int recvn(int sockfd, void * buff, int len);

int tcpInit(const char * ip, const char * port);

int epollAddFd(int epfd, int fd);
int epollDelFd(int epfd, int fd);
//处理客户端发过来的消息
int handleMessage(task_t *task);
//执行任务的总的函数
void doTask(task_t * task);
//每一个具体命令的执行
void cdCommand(task_t * task);
void lsCommand(task_t * task);
void pwdCommand(task_t * task);
void mkdirCommand(task_t * task);
void rmdirCommand(task_t * task);
void notCommand(task_t * task);
void putsCommand(task_t * task);
void getsCommand(task_t * task);
// 业务接口
int user_login(int net_fd, char *logged_in_username);
int transferFile(int peerfd);

// 日志记录
int logger_init(const char *log_file_name);
int logger_close();
void log_info(const char *type, const char *content, const char *file, int line, const char *function);

#endif

